﻿/**********************************************************************************
 * Project Name :   
 * Remarks      :  
 * Class Name   :  BaseUserServiceTest 
 * Version      :  v1.0.0.0 
 * Author       :  Joey Liang 
 * Description  :  
 * Created Time :  2013/10/31 22:44:22
 * Update Man   :  Joey Liang
 * Update Time  :  2013/10/31 22:44:22
************************************************************************/

using IdleTest;
using IdleTest.MSTest;
using IdleTest.EFAndMVCDemo.IServices;
using IdleTest.EFAndMVCDemo.IRepositories.Fakes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using IdleTest.EFAndMVCDemo.Models;
using IdleTest.EFAndMVCDemo.IRepositories;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using IdleTest.EFAndMVCDemo.TestUtilities;

namespace IdleTest.EFAndMVCDemo.ServiceTest
{
    public abstract class BaseUserServiceTest
    {
        protected UserTestHelper UserTestHelper = new UserTestHelper();

        private IUserRepository userRepository;

        protected IList<UserModel> ExistedUsers;

        protected abstract IUserService UserService
        {
            get;
        }
        
        /// <summary>
        /// IUserRepository模拟对象
        /// </summary>
        public virtual IUserRepository UserRepository
        {
            get
            {
                if (this.userRepository == null)
                {
                    StubIUserRepository stubUserRepository = new StubIUserRepository();
                    //模拟Get方法
                    stubUserRepository.GetExpressionOfFuncOfUserModelBooleanFuncOfIQueryableOfUserModelIOrderedQueryableOfUserModelString
                        = (x, y, z) =>
                        {
                            return this.ExistedUsers.Where<UserModel>(x.Compile());
                        };

                    //模拟GetSingle方法
                    stubUserRepository.GetSingleString = p => this.ExistedUsers.FirstOrDefault<UserModel>(o => o.LoginName == p);

                    //模拟Insert方法
                    stubUserRepository.InsertUserModel = (p) => this.ExistedUsers.Add(p);

                    this.userRepository = stubUserRepository;
                }

                return this.userRepository;
            }
        }

        [TestInitialize]
        public void InitUserList()
        {
            //每次测试前都初始化
            this.ExistedUsers = new List<UserModel> { UserTestHelper.ExistedUser };
        }

        #region Login Test
        [TestCategory("登陆场景")]
        public virtual void 当用户信息全部为空或账户为空或密码为空或账户错误或密码错误或账户密码均错误都登陆失败()
        {
            //验证登陆失败的场景
            AssertCommon.IsBoolean<UserModel>(
                new UserModel[] { 
                    null, new UserModel(),
                    new UserModel { LoginName = string.Empty, Password = UserTestHelper.ExistedPassword }, //账户为空
                    new UserModel { LoginName = UserTestHelper.ExistedLoginName, Password = string.Empty }, //密码为空
                    new UserModel { 
                        LoginName = UserTestHelper.ExistedLoginName, Password = UserTestHelper.NotExistedPassword 
                    }, //密码错误
                    new UserModel { 
                        LoginName = UserTestHelper.NotExistedLoginName, Password = UserTestHelper.NotExistedPassword 
                    },  //账户密码错误                    
                    new UserModel { 
                        LoginName = UserTestHelper.NotExistedLoginName, Password = UserTestHelper.ExistedLoginName 
                    }  //账户错误
                }, false, p => UserService.Login(p));
        }

        [TestCategory("登陆场景")]
        public virtual void 当账户密码全部正确时登陆成功()
        {
            //账户密码正确，验证成功，这里假设正确的账户密码是"zhangsan"、"123456"
            UserModel model = new UserModel
            {
                LoginName = UserTestHelper.ExistedLoginName,
                Password = UserTestHelper.ExistedPassword
            };
            AssertCommon.IsBoolean(true, UserService.Login(model));
        }

        #endregion

        #region RegisterTest
        [TestCategory("注册场景")]
        public virtual void 当用户信息全为空或账户为空或密码为空或账户已存在时注册失败()
        {
            //验证注册失败的场景
            AssertCommon.IsBoolean<UserModel>(
                new UserModel[] { 
                    null, new UserModel(),
                    new UserModel { LoginName = string.Empty, Password = UserTestHelper.NotExistedPassword }, //账户为空
                    new UserModel { LoginName = UserTestHelper.NotExistedLoginName, Password = string.Empty }, //密码为空
                    new UserModel { 
                        LoginName = UserTestHelper.ExistedLoginName, Password = UserTestHelper.NotExistedPassword 
                    }, //账户已存在
                }, false, p => UserService.Register(p));
        }

        [TestCategory("注册场景")]
        public virtual void 当账号密码均不为空且账号未存在则注册成功并且注册后的用户信息与注册输入的保持完全一致()
        {

            //验证注册成功的场景
            //密码与他人相同也可注册
            UserModel register1 = new UserModel { LoginName = "register1", Password = UserTestHelper.ExistedPassword };
            UserModel register2 = new UserModel { LoginName = "register2", Password = UserTestHelper.NotExistedPassword };
            UserModel register3 = new UserModel
            {
                LoginName = "register3",
                Password = UserTestHelper.NotExistedPassword,
                Age = 18
            };

            AssertCommon.IsBoolean<UserModel>(
                new UserModel[] { register1, register2, register3 }, true, p => UserService.Register(p));

            //获取用户且应与注册的信息保持一致
            UserModel actualRegister1 = UserService.GetModel(register1.LoginName);
            UserTestHelper.AssertEqual(register1, actualRegister1);

            UserModel actualRegister2 = UserService.GetModel(register2.LoginName);
            UserTestHelper.AssertEqual(register2, actualRegister2);

            UserModel actualRegister3 = UserService.GetModel(register3.LoginName);
            UserTestHelper.AssertEqual(register3, actualRegister3);
        }
        #endregion

        //该方法可不需要业务人员参与
        public virtual void GetModelTest()
        {
            AssertCommon.IsNull<string, UserModel>(TestCommon.GetEmptyStrings(), true, p => UserService.GetModel(p));
            AssertCommon.IsNull(true, UserService.GetModel(UserTestHelper.NotExistedLoginName));

            UserModel actual = UserService.GetModel(UserTestHelper.ExistedLoginName);
            UserTestHelper.AssertEqual(UserTestHelper.ExistedUser, actual);
        }
    }
}
